package com.xywh.wanandroid.compose_ui.main.bottomBar

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SecondaryScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRowDefaults
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableIntState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.ItemSnapshotList
import androidx.paging.compose.collectAsLazyPagingItems
import com.xywh.composeLibrary.ext.ListFloatingActionButton
import com.xywh.composeLibrary.statex.StateCompose
import com.xywh.wanandroid.compose_ui.system.KnowledgeTreeItem
import com.xywh.wanandroid.data.model.bean.KnowledgeTreeItem
import com.xywh.wanandroid.data.model.bean.NavigationArticle
import com.xywh.wanandroid.data.model.bean.NavigationBeanItem
import com.xywh.wanandroid.ext.randomColor
import com.xywh.wanandroid.viewmodel.MainComposeViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlin.math.abs

@Composable
fun SystemScreen(
    innerPadding: PaddingValues,
    mainComposeViewModel: MainComposeViewModel,
    scope: CoroutineScope,
    navigateWebView: (String, String) -> Unit,
    navigateKnowledge: (String, KnowledgeTreeItem) -> Unit
) {

    SystemContent(
        innerPadding,
        mainComposeViewModel,
        scope,
        navigateWebView = navigateWebView,
        navigateKnowledge = navigateKnowledge
    )
}

@Composable
fun SystemContent(
    innerPadding: PaddingValues,
    viewModel: MainComposeViewModel,
    scope: CoroutineScope,
    navigateWebView: (String, String) -> Unit,
    navigateKnowledge: (String, KnowledgeTreeItem) -> Unit
) {

    val systemTree = arrayListOf("体系", "导航")




    Box(
        modifier = Modifier
            .fillMaxSize()
    ) {


        Column(
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight()
        ) {

            val state = TopTabRow(innerPadding, systemTree)

            if (state == 0) {
                TopTabRow1(viewModel, innerPadding, navigateKnowledge)
            } else {
                TopTabRow2(viewModel, innerPadding, scope, navigateWebView)
            }
        }


    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun TopTabRow2(
    viewModel: MainComposeViewModel,
    innerPadding: PaddingValues,
    scope: CoroutineScope,
    navigateWebView: (String, String) -> Unit
) {


    val navigationListState = rememberLazyListState()

    val navigationListRightState = rememberLazyListState()

    val pxValue = with(LocalDensity.current) { 40.dp.toPx() }

    val navigationList = viewModel.navigationList.collectAsLazyPagingItems()

    val selectedIndex = rememberSaveable {
        mutableIntStateOf(0)
    }

    StateCompose(navigationList) {

        val refresh by remember { mutableStateOf(false) }
        val pullRefreshState = rememberPullRefreshState(refresh, {
            navigationList.refresh()
        })
        Box(
            modifier = Modifier
                .fillMaxSize()
                .pullRefresh(pullRefreshState)
        ) {

            Row(
                Modifier
                    .fillMaxWidth()
                    .fillMaxHeight()
            ) {
                navigationList.itemSnapshotList.let {
                    LeftLazyColumn(
                        navigationListState,
                        it,
                        scope,
                        pxValue,
                        navigationListRightState,
                        selectedIndex
                    )
                    Divider(
                        Modifier
                            .width(1.dp)
                            .fillMaxHeight(),
                        color = Color(0xFFE6E6E6)
                    )

                    RightLazyColumn(
                        navigationListRightState,
                        it,
                        navigateWebView = navigateWebView
                    ) {
                        selectedIndex.intValue = 0
                        scope.launch {
                            navigationListState.animateScrollToItem(0)
                        }
                    }
                }

            }
            PullRefreshIndicator(
                refresh,
                pullRefreshState,
                Modifier.align(Alignment.TopCenter),
                scale = true
            )
        }
    }


}

@Composable
private fun RightLazyColumn(
    navigationListRightState: LazyListState,
    navigationList: ItemSnapshotList<NavigationBeanItem>,
    navigateWebView: (String, String) -> Unit,
    scrollToTop: () -> Unit = {}
) {

    Box {
        LazyColumn(
            state = navigationListRightState,
            modifier = Modifier
//            .padding(bottom = innerPadding.calculateBottomPadding())
                .fillMaxWidth()
                .background(Color.White),
        ) {
            if (navigationList.size > 0) {
                items(
                    count = navigationList.size,
                    key = { index ->
                        val article = navigationList[index]
                        "${article?.cid ?: ""}${index}"
                    }) {
                    val itemData = navigationList[it]
                    Column(
                        Modifier
                            .fillMaxWidth()
                            .fillMaxHeight()
                    ) {

                        if (itemData != null) {
                            Text(
                                text = itemData.name,
                                color = Color.Black,
                                fontWeight = FontWeight.Bold,
                                fontSize = 12.sp,
                                modifier = Modifier.padding(start = 10.dp, top = 10.dp)
                            )
                        }

                        val articles = itemData?.articles
                        if (articles != null) {
                            if (articles.isNotEmpty())
                                FlowlayoutCompose(articles, navigateWebView)
                        }

                    }
                }
            }


        }
        Box(
            Modifier
                .padding(10.dp)
                .align(Alignment.BottomEnd)
        ) {
            ListFloatingActionButton(
                rememberCoroutineScope(),
                navigationListRightState,
                scrollToTop
            )
        }
    }

}

@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun FlowlayoutCompose(
    articles: List<NavigationArticle>,
    navigateWebView: (String, String) -> Unit
) {

    FlowRow(
        Modifier
            .padding(start = 10.dp, end = 10.dp)
    ) {
        repeat(articles.size) {
            val itemArticle = articles[it]
            Box(
                Modifier
                    .padding(start = 5.dp, end = 5.dp, top = 5.dp)
                    .height(30.dp)
                    .graphicsLayer {
                        clip = true
                        shape = RoundedCornerShape(10)
                    }
                    .background(Color(0xFFF5F5F5))
                    .padding(8.dp, 2.dp)
                    .clickable {
                        navigateWebView.invoke(itemArticle.title, itemArticle.link)
                    }


            ) {
                Text(
                    text = itemArticle.title,
//                    color = Color.Black,
                    color = Color(randomColor()),
                    modifier = Modifier.align(Alignment.Center),
                    fontSize = 10.sp,
                    textAlign = TextAlign.Center,

                    )

            }
        }
    }
}

@Composable
private fun LeftLazyColumn(
    navigationListState: LazyListState,
    navigationList: ItemSnapshotList<NavigationBeanItem>,
    scope: CoroutineScope,
    pxValue: Float,
    navigationListRightState: LazyListState,
    selectedIndex: MutableIntState
) {

    LazyColumn(
        state = navigationListState,
        modifier = Modifier
//            .padding(bottom = innerPadding.calculateBottomPadding())
            .width(100.dp)
            .background(Color(0xFFF5F5F5)),
    ) {

        if (navigationList.size > 0) {
            items(
                count = navigationList.size,
                key = { index ->
                    val navigation = navigationList[index]
                    "${navigation?.cid ?: ""}${index}"
                }) {


                var fontWeight: FontWeight = FontWeight.Normal
                var background: Color = Color(0xFFF5F5F5)
                var color: Color = Color.Black
                if (selectedIndex.intValue == it) {
                    fontWeight = FontWeight.Bold
                    background = Color.White
                    color = Color(0xFF00BCD4)
                }
                val itemData = navigationList[it] ?: return@items

                Box(
                    Modifier
                        .height(40.dp)
                        .fillMaxWidth()
                        .background(background)
                        .clickable {
                            selectedIndex.intValue = it

                            //第一个显示的下标
                            val firstVisibleItemIndex =
                                navigationListState.firstVisibleItemIndex

                            //页面显示的item数量
                            val visibleItemsInfoSize =
                                navigationListState.layoutInfo.visibleItemsInfo.size

                            //中间位置的下表 = 第一个显示的下标 加上 页面显示的item数量的一半
                            val centerPosition =
                                (firstVisibleItemIndex + visibleItemsInfoSize / 2) - 1

                            //选择的位置的下标与中间位置的下标差的绝对值
                            val cha = abs(selectedIndex.intValue - centerPosition)

                            //移动选择的item到中间的位置
                            if (centerPosition != selectedIndex.intValue) {//选择的位置与中间位置不等时，把选择的位置移动到中间位置

                                if (selectedIndex.intValue > centerPosition) { //选择的位置大于中间位置 向下移动
                                    scope.launch {
                                        navigationListState.animateScrollBy(cha * pxValue)
                                    }
                                } else { //选择的位置小于中间位置 向上移动
                                    scope.launch {
                                        navigationListState.animateScrollBy(-cha * pxValue)
                                    }
                                }

                            }

                            scope.launch {
                                navigationListRightState.animateScrollToItem(
                                    selectedIndex.intValue
                                )
                            }

                        }
                ) {
                    Text(
                        text = itemData.name,
                        modifier = Modifier.align(Alignment.Center),
                        color = color,
                        fontWeight = fontWeight,
                        fontSize = 12.sp,
                        textAlign = TextAlign.Center,
                    )
                }

            }
        }


    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun TopTabRow1(
    viewModel: MainComposeViewModel,
    innerPadding: PaddingValues,
    navigateKnowledge: (String, KnowledgeTreeItem) -> Unit
) {

    val knowledgeTree = viewModel.knowledgeTree.collectAsLazyPagingItems()

    StateCompose(knowledgeTree) {


        val refresh by remember { mutableStateOf(false) }
        val pullRefreshState = rememberPullRefreshState(refresh, {
            knowledgeTree?.refresh()
        })

        Box(
            Modifier
                .fillMaxSize()
                .pullRefresh(pullRefreshState)
        ) {
            val listState = rememberLazyListState()

            LazyColumn(
                state = listState,
                // consume insets as scaffold doesn't do it by default
                modifier = Modifier
                    .consumeWindowInsets(innerPadding),
//            contentPadding = innerPadding,
            ) {

                knowledgeTree.itemSnapshotList.let { knowledgeTree ->

                    if (knowledgeTree.size > 0) {
                        items(
                            count = knowledgeTree.size,
                            key = { index ->
                                val knowledge = knowledgeTree[index]
                                "${knowledge?.id ?: ""}${index}"
                            }) {
                            val itemData = knowledgeTree[it] ?: return@items
                            KnowledgeTreeItem(itemData) { title, id ->
                                navigateKnowledge.invoke(title, itemData)
                            }
                        }
                    }
                }


            }
            Box(
                Modifier
                    .padding(10.dp)
                    .align(Alignment.BottomEnd)
            ) {
                ListFloatingActionButton(rememberCoroutineScope(), listState)
            }


            PullRefreshIndicator(
                refresh,
                pullRefreshState,
                Modifier.align(Alignment.TopCenter),
                scale = true
            )
        }

    }

}

@Composable
private fun TopTabRow(
    innerPadding: PaddingValues,
    systemTree: ArrayList<String>
): Int {
    var state by rememberSaveable { mutableIntStateOf(0) }

    SecondaryScrollableTabRow(
        modifier = Modifier
//            .padding(top = innerPadding.calculateTopPadding())
            .fillMaxWidth(),
        selectedTabIndex = state,
        containerColor = MaterialTheme.colorScheme.primary,
        contentColor = Color.White,
        edgePadding = 0.dp,
        divider = { HorizontalDivider(color = Color.Transparent) },
        indicator = { tabPositions ->
            TabRowDefaults.SecondaryIndicator(
                Modifier.tabIndicatorOffset(tabPositions[state]),
                color = Color.White
            )
        }
    ) {
        systemTree.forEachIndexed { index, systemTreeItem ->
            Tab(
                selected = state == index,
                onClick = {
                    state = index
//                                    tabOnclick.invoke(systemTreeItem.id)
                },
                text = {

                    val fontWeight = if (state == index) {
                        FontWeight.Bold
                    } else {
                        FontWeight.Normal
                    }
                    Text(systemTreeItem, fontWeight = fontWeight)

                }
            )
        }

    }
    return state
}

